home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / Fl_Gl_Choice.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-16  |  5.5 KB  |  211 lines

  1. //
  2. // "$Id: Fl_Gl_Choice.cxx,v 1.5.2.1 1999/09/16 05:34:25 bill Exp $"
  3. //
  4. // OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. #include <config.h>
  27. #if HAVE_GL
  28.  
  29. #include <FL/Fl.H>
  30. #include <FL/x.H>
  31. #include <stdlib.h>
  32.  
  33. #include "Fl_Gl_Choice.H"
  34.  
  35. static Fl_Gl_Choice *first;
  36. GLXContext fl_first_context;
  37.  
  38. // this assummes one of the two arguments is zero:
  39. // We keep the list system in Win32 to stay compatible and interpret
  40. // the list later...
  41. Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) {
  42.   Fl_Gl_Choice *g;
  43.   
  44.   for (g = first; g; g = g->next)
  45.     if (g->mode == mode && g->alist == alist) 
  46.       return g;
  47.  
  48. #ifndef WIN32    
  49.   const int *blist;
  50.   int list[32];
  51.     
  52.   if (alist)
  53.     blist = alist;
  54.   else {
  55.     int n = 0;
  56.     if (mode & FL_INDEX) {
  57.       list[n++] = GLX_BUFFER_SIZE;
  58.       list[n++] = 8; // glut tries many sizes, but this should work...
  59.     } else {
  60.       list[n++] = GLX_RGBA;
  61.       list[n++] = GLX_GREEN_SIZE;
  62.       list[n++] = (mode & FL_RGB8) ? 8 : 1;
  63.       if (mode & FL_ALPHA) {
  64.     list[n++] = GLX_ALPHA_SIZE;
  65.     list[n++] = 1;
  66.       }
  67.       if (mode & FL_ACCUM) {
  68.     list[n++] = GLX_ACCUM_GREEN_SIZE;
  69.     list[n++] = 1;
  70.     if (mode & FL_ALPHA) {
  71.       list[n++] = GLX_ACCUM_ALPHA_SIZE;
  72.       list[n++] = 1;
  73.     }
  74.       }
  75.     }
  76.     if (mode & FL_DOUBLE) {
  77.       list[n++] = GLX_DOUBLEBUFFER;
  78.     }
  79.     if (mode & FL_DEPTH) {
  80.       list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
  81.     }
  82.     if (mode & FL_STENCIL) {
  83.       list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
  84.     }
  85. #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
  86.     if (mode & FL_MULTISAMPLE) {
  87.       list[n++] = GLX_SAMPLES_SGIS;
  88.       list[n++] = 4; // value Glut uses
  89.     }
  90. #endif
  91.     list[n] = 0;
  92.     blist = list;
  93.   }
  94.     
  95.   fl_open_display();
  96.   XVisualInfo *vis = glXChooseVisual(fl_display, fl_screen, (int *)blist);
  97.   if (!vis) {
  98. # if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
  99.     if (mode&FL_MULTISAMPLE) return find(mode&~FL_MULTISAMPLE,0);
  100. # endif
  101.     return 0;
  102.   }
  103.  
  104. #else
  105.  
  106.   PIXELFORMATDESCRIPTOR pfd = { 
  107.     sizeof(PIXELFORMATDESCRIPTOR), 1, 
  108.     PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
  109.     PFD_TYPE_RGBA, 8 };
  110.  
  111.   if (mode & FL_INDEX) {
  112.     pfd.iPixelType = PFD_TYPE_COLORINDEX;
  113.     pfd.cColorBits = 8;
  114.   } else {
  115.     if (mode & FL_ALPHA) pfd.cAlphaBits = 8;
  116.     if (mode & FL_ACCUM) {
  117.       pfd.cAccumBits = 6;    // Wonko: I didn't find any documentation on those bits
  118.       pfd.cAccumGreenBits = 1;    // Wonko: They don't seem to get any support yet (4/98)
  119.       if (mode & FL_ALPHA) pfd.cAccumAlphaBits = 1;
  120.     }
  121.   }
  122.   if (mode & FL_DOUBLE) pfd.dwFlags |= PFD_DOUBLEBUFFER;
  123.   if (mode & FL_DEPTH) pfd.cDepthBits = 16;
  124.   if (mode & FL_STENCIL) pfd.cStencilBits = 1;
  125.   pfd.bReserved = 1; // always ask for overlay
  126.  
  127. #endif
  128.  
  129.   g = new Fl_Gl_Choice;
  130.   g->mode = mode;
  131.   g->alist = alist;
  132.   g->next = first;
  133.   first = g;
  134.  
  135. #ifdef WIN32
  136.   memcpy(&g->pfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR));
  137.   g->d = ((mode&FL_DOUBLE) != 0);
  138.   g->r = (mode & FL_INDEX);
  139.   g->o = 0; // not an overlay
  140. #else
  141.   g->vis = vis;
  142.   g->colormap = 0;
  143.   int i;
  144.   glXGetConfig(fl_display, vis, GLX_DOUBLEBUFFER, &i); g->d = i;
  145.   glXGetConfig(fl_display, vis, GLX_RGBA, &i); g->r = i;
  146.   glXGetConfig(fl_display, vis, GLX_LEVEL, &i); g->o = i;
  147.  
  148.   if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
  149.       vis->visualid == fl_visual->visualid &&
  150.       !getenv("MESA_PRIVATE_CMAP"))
  151.     g->colormap = fl_colormap;
  152.   else
  153.     g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
  154.                   vis->visual, AllocNone);
  155. #endif
  156.  
  157.   return g;
  158. }
  159.  
  160. #ifdef WIN32
  161.  
  162. HDC fl_private_dc(Fl_Window* w, int mode, Fl_Gl_Choice **gp) {
  163.   Fl_X* i = Fl_X::i(w);
  164.   if (!i->private_dc) {
  165.     i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
  166.     Fl_Gl_Choice *g = Fl_Gl_Choice::find(mode, 0);
  167.     if (gp) *gp = g;
  168.     int pixelFormat = ChoosePixelFormat(i->private_dc, &g->pfd);
  169.     if (!pixelFormat) {Fl::error("Insufficient GL support"); return NULL;}
  170.     SetPixelFormat(i->private_dc, pixelFormat, &g->pfd);
  171. #if USE_COLORMAP
  172.     if (fl_palette) SelectPalette(i->private_dc, fl_palette, FALSE);
  173. #endif
  174.   }
  175.   return i->private_dc;
  176. }
  177.  
  178. #endif
  179.  
  180. static GLXContext cached_context;
  181.  
  182. static Fl_Window* cached_window;
  183.  
  184. void fl_set_gl_context(Fl_Window* w, GLXContext c) {
  185.   if (c != cached_context || w != cached_window) {
  186.     cached_context = c;
  187.     cached_window = w;
  188. #ifdef WIN32
  189.     wglMakeCurrent(Fl_X::i(w)->private_dc, c);
  190. #else
  191.     glXMakeCurrent(fl_display, fl_xid(w), c);
  192. #endif
  193.   }
  194. }
  195.  
  196. void fl_no_gl_context() {
  197.   cached_context = 0;
  198.   cached_window = 0;
  199. #ifdef WIN32
  200.   wglMakeCurrent(0, 0);
  201. #else
  202.   glXMakeCurrent(fl_display, 0, 0);
  203. #endif
  204. }
  205.  
  206. #endif
  207.  
  208. //
  209. // End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.1 1999/09/16 05:34:25 bill Exp $".
  210. //
  211.